package cn.com.sbell.vss.ems.dao.impl;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.com.sbell.vss.BaseDao;
import cn.com.sbell.vss.Util;
import cn.com.sbell.vss.VssConstants;
import cn.com.sbell.vss.VssException;
import cn.com.sbell.vss.ems.dao.IUserDao;
import cn.com.sbell.vss.ems.entity.User;
import cn.com.sbell.vss.ems.entity.UserRole;
import cn.com.sbell.vss.util.VssValidator;

public class UserDaoImpl extends BaseDao implements IUserDao {

  public String insert(User user, UserRole[] userRoles) {
    user.setId(generateRandomGUID());
		if(Util.strIsNull(user.getUserNumber())){
			user.setUserNumber(user.getId());
		}

    try {
      getSqlMapClient().startTransaction();
      getSqlMapClient().startBatch();

      getSqlMapClient().insert("insertUser", user);

      if (userRoles != null) {
        for (int i = 0; i < userRoles.length; i++) {
					if( userRoles[i] != null ){
            UserRole userRole = userRoles[i];
						userRole.setUserId(user.getId());
            userRole.setId(generateRandomGUID());
            getSqlMapClient().insert("insertUserRole", userRole);
          }
        }
      }

      getSqlMapClient().executeBatch();
      getSqlMapClient().commitTransaction();
      return user.getId();
    } catch (SQLException e) {
      log.error("SQLException:", e);
      throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
    } finally {
      try {
        getSqlMapClient().endTransaction();
      } catch (SQLException e) {
        log.error("SQLException:", e);
        throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
      }
    }

  }

  public void update(User user, UserRole[] userRoles,boolean editRole) {
		if(Util.strIsNull(user.getUserNumber())){
			user.setUserNumber(user.getId());
		}

    try {
      getSqlMapClient().startTransaction();
      getSqlMapClient().startBatch();

      getSqlMapClient().update("updateUser", user);

			if(editRole){
        // delete all the areaId and roleId in UserRole
        HashMap param = new HashMap();
        param.put("userId", user.getId());
        getSqlMapClient().delete("deleteUserRoles", param);
        if (userRoles != null) {
          for (int i = 0; i < userRoles.length; i++) {
            if (userRoles[i] != null) {
              UserRole userRole = userRoles[i];
              userRole.setId(generateRandomGUID());
							userRole.setUserId(user.getId());
              getSqlMapClient().insert("insertUserRole", userRole);
            }
          }
        }
      }
      getSqlMapClient().executeBatch();
      getSqlMapClient().commitTransaction();

    } catch (SQLException e) {
      log.error("SQLException:", e);
      throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
    } finally {
      try {
        getSqlMapClient().endTransaction();
      } catch (SQLException e) {
        log.error("SQLException:", e);
        throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
      }
    }
  }

  /**
   * delete user by primary key (id)
   *
   * @param pk
   *            String
   */
  public void delete(String pk) {
    Map paraMap = new HashMap();
    paraMap.put("id", pk);
    delete(paraMap);
  }

  /**
   * delete user by para map
   *
   * @param paraMap
   *            Map
   */
  public void delete(Map paraMap) {
    try {
      List lUser = this.find(paraMap);
      if (!Util.listIsNull(lUser)) {
        getSqlMapClient().startTransaction();
        getSqlMapClient().startBatch();

        for (int i = 0; i < lUser.size(); i++) {
          User user = (User) lUser.get(i);
          HashMap paraHashMap = new HashMap();
          paraHashMap.put("userId", user.getId());
          getSqlMapClient().delete("deleteUserRoles", paraHashMap);

          //set adminusername null in organization
          Map orgMap = new HashMap();
          orgMap.put("adminUsername",user.getUsername());
          List lOrgnization = getSqlMapClient().
            queryForList("findOrganization",orgMap);
          if(!Util.listIsNull(lOrgnization)){
            Map updateMap = new HashMap();
            updateMap.put("username1",null);
            updateMap.put("username2",user.getUsername());
            getSqlMapClient().update("updateAdminUsername",updateMap);
          }

        }



        getSqlMapClient().delete("deleteUser", paraMap);
        getSqlMapClient().executeBatch();
        getSqlMapClient().commitTransaction();

      }
    } catch (SQLException e) {
      log.error("SQLException:", e);
      throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
    } finally {
      try {
        getSqlMapClient().endTransaction();
      } catch (SQLException e) {
        log.error("SQLException:", e);
        throw new VssException(VssConstants.CODE_DATABASE_ACCESS_ERROR);
      }
    }

  }

  public List find(Map param) {
    return getSqlMapClientTemplate().queryForList("findUser", param);
  }

  public List findEx(Map param) {
    return getSqlMapClientTemplate().queryForList("findUserEx", param);
  }

  public User find(String pk) {

    // validate pk: must not null
    VssValidator.validateMaxLength("field.id", pk, true, 32);

    // prepare query parameters
    HashMap userIdHashMap = new HashMap();
    userIdHashMap.put("id", pk);

    // find videoServers
    List users = find(userIdHashMap);
    if ( (users != null) && (users.size() > 0))
      // return the first one: and only one for one PK
      return (User) users.get(0);
    else
      return null;
  }

  public User findByName(String name) {

    // prepare query parameters
    HashMap usernameHashMap = new HashMap();
    usernameHashMap.put("username", name);

    // find videoServers
    List users = getSqlMapClientTemplate().queryForList("findByUsername",
      usernameHashMap);

    if ( (users != null) && (users.size() > 0))
      // return the first one: and only one for one PK
      return (User) users.get(0);
    else
      return null;
  }

	public User findByUserNumber(String userNumber){
		// prepare query parameters
		HashMap paraMap = new HashMap();
		paraMap.put("userNumber", userNumber);

		// find videoServers
		List users = getSqlMapClientTemplate().queryForList("findByUserNumber",
			paraMap);

		if ( (users != null) && (users.size() > 0))
			// return the first one
			return (User) users.get(0);
		else
			return null;
  }
  public int countUser(Map params) {
    Integer c = (Integer) getSqlMapClientTemplate().queryForObject(
      "countUser", params);
    return c.intValue();
  }

	 /**
		 * In the orgznization,
		 * whether userNumber of user is not in between userNumberFrom and userNumberTo
		 * @param userNumberFrom String
		 * @param userNumberTo String
		 * @return boolean
		 */
	public boolean isUserNumberInBetweenFromAndTo(String userNumberFrom,
																								String userNumberTo,
																								String organizationId){
		Map map = new HashMap();
		map.put("organizationId",organizationId);
		map.put("userNumberFrom",userNumberFrom);
		map.put("userNumberTo",userNumberTo);
		Integer c = (Integer) getSqlMapClientTemplate().queryForObject(
				"countUserByUserNumberFromAndUserFromTo", map);
		if (c.intValue() > 0) {
			return true;
		} else {
			return false;
		}
		}

}
